import json
import random
import datetime
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QMessageBox, QTableWidgetItem, QFileDialog
import matplotlib
import matplotlib.pyplot as plt


from PyQt5.QtGui import  QPixmap
from PyQt5.QtWidgets import QMainWindow, QApplication
import sys
from PyQt5 import QtCore

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False
matplotlib.use('TkAgg')
from matplotlib import pyplot as plt

from Ui.ui_mainwindow import Ui_MainWindow
import logging
# from online_exercise_main import onlineExerciseMain
# 配置日志记录
logging.basicConfig(level=logging.INFO)
from countdown import Countdown
from mysql_use import mysqlUse


class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, user_id):
        super().__init__()
        self.setupUi(self)
        self.user_id = user_id
        self.db = mysqlUse()
        self.find_user_info()
        self.LIMIT_NUM = 10     #每页限制10题
        self.MAX_cals_num = 30  #每套习题最多30道
        self.difficulty_type = 0
        self.rows = []
        self.countdown=0
        self.expression_quantity = 0
        self.limit_time = 0
        self.new_prac_id = 0
        self.pages = []
        self.page_num = 0
        self.current_page_num = 0
        self.time_state = 0
        # # 连接主页面按钮的点击事件到自定义槽函数
        # 点击在线练习按钮
        self.pb_online_exercise.clicked.connect(self.on_online_exercise_clicked)
        # 点击入练习按钮
        self.pb_import_exercise.clicked.connect(self.on_import_exercise_clicked)
        # 点击错题本按钮
        self.pb_error_book.clicked.connect(self.on_error_book_clicked)
        # 点击结果分析按钮
        self.pb_result_analysis.clicked.connect(self.on_result_analysis_clicked)
        # 点击个人中心按钮
        self.pb_personal_center.clicked.connect(self.on_personal_center_clicked)
        # 在线练习界面按钮操作
        self.connect_online_exercise_signals()
        # 暂停与继续计时按钮
        self.pb_pause.clicked.connect(self.countdown_pause_or_resume)
        self.find_user_info()
        # 连接 itemDoubleClicked 信号到自定义的槽函数
        self.tableWidget.itemDoubleClicked.connect(self.on_table_item_double_clicked)


    def find_user_info(self):
        user_info=self.db.find_user_info(self.user_id)
        print(user_info)
        self.label_name.setText(user_info['username'])
        self.label_mailbox.setText(user_info['email'])
        self.label_grade.setText(str(user_info['grade']))

    def countdown_pause_or_resume(self):
        if self.time_state == 0:
            self.time_state = 1
            self.countdown.pause()
            self.pb_pause.setText("继续")
        else:
            self.time_state = 0
            self.countdown.resume()
            self.pb_pause.setText("暂停")

    def update_countdown_display(self, value):
        minutes, seconds = divmod(value, 60)
        self.l_countdown_2.setText(f'{minutes:02}:{seconds:02}')

    def jump_to_page_error_edition_0(self):
        self.stackedWidget.setCurrentIndex(6)

    def jump_to_page_main(self):
        self.stackedWidget.setCurrentIndex(0)

    def jump_to_page_select_difficulty(self):
        self.stackedWidget.setCurrentIndex(1)

    def jump_to_page_easy_medium(self):
        self.stackedWidget.setCurrentIndex(2)

    def jump_to_page_hard(self):
        self.stackedWidget.setCurrentIndex(3)

    def jump_to_page_online_practice(self):
        self.stackedWidget.setCurrentIndex(4)

    def on_online_exercise_clicked(self):
        """当在线练习按钮被点击时调用此方法"""
        logging.info("Online Exercise clicked")
        self.jump_to_page_select_difficulty()

    def on_import_exercise_clicked(self):
        """当导入练习按钮被点击时调用此方法"""
        logging.info("Import Exercise clicked")
        self.stackedWidget.setCurrentIndex(10)

    def on_error_book_clicked(self):
        """当错题本按钮被点击时调用此方法"""
        logging.info("Error Book clicked")
        self.stackedWidget.setCurrentIndex(6)
        self.display_wrongrecord()

    def on_result_analysis_clicked(self):
        """当结果分析按钮被点击时调用此方法"""
        logging.info("Result Analysis clicked")
        self.stackedWidget.setCurrentIndex(8)
        self.draw_charts()

    def on_personal_center_clicked(self):
        """当个人中心按钮被点击时调用此方法"""
        logging.info("Personal Center clicked")
        self.stackedWidget.setCurrentIndex(9)

    def choose_easy(self):
        """当简单模式按钮被点击时调用此方法"""
        self.jump_to_page_easy_medium()
        self.difficulty_type = 1

    def choose_medium(self):
        """当中等模式按钮被点击时调用此方法"""
        self.jump_to_page_easy_medium()
        self.difficulty_type = 2

    def choose_hard(self):
        """当困难模式按钮被点击时调用此方法"""
        self.jump_to_page_hard()
        self.difficulty_type = 3

    def start_exercise0(self):
        """当简单获普通模式开始做题按钮被点击时调用此方法"""
        self.clear_page_online_practice()
        self.jump_to_page_online_practice()
        self.expression_quantity = int(self.cb_expression_quantity_0.currentText())
        print(self.difficulty_type)
        print(self.expression_quantity)
        # 数据库抽取算式，生成习题和使用记录
        self.generate_calculations0()
        # self.rows = onlineExerciseMain().generate_calculations0(1, 12)
        self.current_exercises = self.rows  # 保存当前练习的题目
        # self.current_exercises = [(row[1], row[2]) for row in self.rows]
        print(self.rows)
        self.page_num = self.expression_quantity // self.LIMIT_NUM  # 整除得到页数
        if self.expression_quantity % self.LIMIT_NUM!= 0:  # 如果有余数，则加一页
            self.page_num += 1
        self.pages = [self.rows[i * self.LIMIT_NUM:(i + 1) * self.LIMIT_NUM] for i in range(self.page_num)]
        # self.display_calculations(self.pages[0])
        # for i, page in enumerate(self.pages):
        #     print(f"Page {i + 1}: {page}")
        self.l_page.setText("1")
        self.display_calculations()
        self.start_contdown()

    def start_contdown(self):
        # 初始化并启动倒计时
        self.limit_time = self.expression_quantity * self.difficulty_type * 20  # 单位 s
        print(f"limit_time:{self.limit_time}")
        self.countdown = Countdown(self.limit_time)
        self.countdown.start()  # 启动倒计时
        self.countdown.countdown_updated.connect(self.update_countdown_display)
        self.countdown.countdown_finished.connect(self.submit_exercise)
        self.time_state = 0  # 重置时间状态为未暂停

    def start_exercise1(self):
        """当困难模式开始做题按钮被点击时调用此方法"""
        self.clear_page_online_practice() # 清除当前在线练习页面上的内容
        self.jump_to_page_online_practice()# 跳转到做习题界面
        # 从设置习题参数界面中获取题目数量和括号数量
        self.expression_quantity = int(self.cb_expression_quantity_1.currentText())
        bracket_quantity = int(self.cb_bracket_quantity.currentText())
        # 验证括号数量，确保不超过题目数量
        if bracket_quantity>self.expression_quantity :
            bracket_quantity = self.expression_quantity
        # 根据题目数量和括号数量从算式基中随机选取对应算式，存储在self.rows中
        self.generate_calculations1(bracket_quantity)
        self.current_exercises = self.rows
        self.set_page()  # 分页
        self.display_calculations()# 显示第一页的计算题
        self.start_contdown()# 启动倒计时器

    def clear_page_online_practice(self):
        try:
            labels = [getattr(self, f'l_{i + 1}', None) for i in range(self.MAX_cals_num)]
            labels2 = [getattr(self, f'label_{i + 1}', None) for i in range(self.MAX_cals_num)]
            line_edits = [getattr(self, f'le_{i + 1}', None) for i in range(self.MAX_cals_num)]

            for i in range(self.MAX_cals_num):
                if labels[i] and hasattr(labels[i], 'setText'):
                    labels[i].setText("")
                if labels2[i] and hasattr(labels2[i], 'setText'):
                    labels2[i].setText("")
                if line_edits[i] and hasattr(line_edits[i], 'setText'):
                    line_edits[i].setText("")

            if hasattr(self.countdown, 'stop'):
                self.countdown.stop()
        except AttributeError as e:
            print(f"An attribute error occurred: {e}")
        except Exception as e:
            print(f"An unexpected error occurred: {e}")

    def display_calculations(self):
        labels = [getattr(self, f'l_{i + 1}') for i in range(self.MAX_cals_num)]
        labels2 = [getattr(self, f'label_{i + 1}') for i in range(self.MAX_cals_num)]
        print("self.rows:", self.rows)  # 打印 self.rows 的内容
        for i in range(self.MAX_cals_num):
            labels[i].setText("")
            labels2[i].setText("")
        for i, row in enumerate(self.rows):
            if i < len(labels):
                labels[i].setText(row[1] if len(row) > 1 else "")  # 如果 row 不够长，则设置为空字符串

    def switch_pages_pre(self):
        if self.current_page_num > 0:
            self.current_page_num -= 1
            # self.display_calculations(self.pages[self.current_page_num])
            self.stackedWidget_lower.setCurrentIndex(self.current_page_num)
            self.l_page.setText(str(self.current_page_num + 1))

    def switch_pages_next(self):
        if self.current_page_num < self.page_num - 1:
            self.current_page_num += 1
            # self.display_calculations(self.pages[self.current_page_num])
            self.stackedWidget_lower.setCurrentIndex(self.current_page_num)
            self.l_page.setText(str(self.current_page_num + 1))

    def submit_exercise(self):
        """提交习题后系统会进行答案批改，结算界面的显示，使用表的增加"""
        # 从界面上获取所有答案输入框和对应的标签
        line_edits = [getattr(self, f'le_{i + 1}') for i in range(self.MAX_cals_num)]
        labels = [getattr(self, f'label_{i + 1}') for i in range(self.MAX_cals_num)]
        sum = self.expression_quantity  # 获取总题数
        right_num = 0   # 初始化正确题数
        for i, row in enumerate(self.rows): # 遍历所有题目
            # 确保索引在有效范围内，并且题目数据完整
            if i < len(line_edits) and i < len(labels) and len(row) > 2:
                try:
                    submit_answer = int(line_edits[i].text())    # 获取用户提交的答案
                    correct_answer = row[2] # 获取正确答案
                    # 批改答案
                    if submit_answer == correct_answer:
                        labels[i].setText("√")  # 如果正确，设置标签为“√”
                        right_num += 1   # 增加正确题数
                    else:
                        labels[i].setText("× " + str(row[2]))  # 如果错误，设置标签为“×”加上正确答案
                        self.db.add_wrongrecord(self.user_id, row[0], submit_answer)    # 记录错误答案到数据库
                except ValueError:
                    # 用户未填写答案，与做错同样操作
                    labels[i].setText("×" + str(row[2]))
                    # 记录未提交答案的情况到数据库
                    self.db.add_wrongrecord_no_answer(self.user_id, row[0])
            else:
                labels[i].setText("×" + str(row[2]))
        #结算界面的显示，使用表的增加
        self.exercise_settlement(right_num,sum)

    def exercise_settlement(self,right_num,sum):
        """结算界面的显示，使用表的增加"""
        self.label_error.setText(str(sum - right_num))# 显示错误题数
        # 计算并显示正确率
        percentage = right_num / sum * 100
        formatted_percentage = "{:.2f}".format(percentage)# 格式化为两位小数
        print(float(formatted_percentage)) # 打印浮点数形式的正确率
        self.label_correct.setText(formatted_percentage + "%")
        # 更新数据库中的练习记录，包括正确题数和总题数，可能还有新的练习ID
        start_time,end_time= self.db.modify_practice(right_num, sum, self.new_prac_id)
        # 计算并显示练习总时间
        if end_time and start_time:
            time_difference = end_time - start_time
            spend_time_seconds = time_difference.total_seconds()  # 获取总秒数
            print(spend_time_seconds)
            self.label_practice.setText(str(int(spend_time_seconds))+"s")  # 显示总秒数
        else:
            self.label_practice.setText("N/A")

    def settlement_exercise(self):
        self.stackedWidget.setCurrentIndex(5)

    def display_wrongrecord(self):
        results, unique_dates_list = self.db.class_wrongrecord(self.user_id)
        print(results)
        print(unique_dates_list)
        if self.tableWidget is not None:
            self.tableWidget.setRowCount(len(results))
            for row, result in enumerate(results):
                self.tableWidget.setItem(row, 0, QTableWidgetItem(result['submit_time0']))
                self.tableWidget.setItem(row, 1, QTableWidgetItem(str(result['error_count'])+"道错题"))
                self.tableWidget.setItem(row, 2, QTableWidgetItem("########双击查看#######"))
        else:
            print("tableWidget 未正确初始化")

    def on_table_item_double_clicked(self, item):
        row = item.row()
        first_column_item = self.tableWidget.item(row, 0)
        if first_column_item is not None:
            print(first_column_item.text())
            self.stackedWidget.setCurrentIndex(7)
            self.display_wrongrecord_calculations(first_column_item.text())
        else:
            print("无法获取第一列数据")

    def display_wrongrecord_calculations(self, wrongrecord_submit_time):
        self.rows=self.db.get_wrongrecord_calculations(wrongrecord_submit_time, self.user_id)
        print(self.rows)  # 包括算式id（如果有的话）+算式+正确答案
        # 确保 tableWidget_2 已经正确创建和初始化
        if self.tableWidget_2 is not None:
            # 设置表格的行数
            self.tableWidget_2.setRowCount(len(self.rows))
            # 设置表格的列数（根据要显示的数据）
            self.tableWidget_2.setColumnCount(3)  # 假设我们要显示算式、正确答案和错误答案
            # 设置表格的列标题（可选）
            self.tableWidget_2.setHorizontalHeaderLabels(['算式', '正确答案', '错误答案'])
            for row, result in enumerate(self.rows):
                # 在第一列添加算式数据
                self.tableWidget_2.setItem(row, 0, QTableWidgetItem(result['expression']))
                # 在第二列添加正确答案数据
                self.tableWidget_2.setItem(row, 1, QTableWidgetItem(str(result['answer'])))
                # 在第三列添加错误答案数据
                self.tableWidget_2.setItem(row, 2, QTableWidgetItem(str(result['wrong_answer'])))
        else:
            print("tableWidget_2 未正确初始化")

    def repractice_the_mistakes(self):
        # 清除当前在线练习页面上的内容
        self.clear_page_online_practice()
        # 提取并转换题目信息，去除表达式末尾的等号
        self.current_exercises = [
            [item['calc_id'], item['expression'].rstrip('='), item['answer']]
            for item in self.rows ]
        # 根据题目数量进行随机抽样或全部使用
        if len(self.rows) > self.MAX_cals_num:   # 随机抽取30个元素
            sampled_rows = random.sample(self.rows, self.MAX_cals_num)
            # 将抽取的元素转换成所需的列表格式
            self.rows = [[item['calc_id'], item['expression'], item['answer'], item['wrong_answer']] for item in
                         sampled_rows]
            self.expression_quantity = self.MAX_cals_num
        else:
            self.rows = [[item['calc_id'], item['expression'], item['answer'], item['wrong_answer']] for item in
                         self.rows]# 如果 self.rows 不超过30个元素，则直接转换
            self.expression_quantity = len(self.rows)
        self.set_page() #分页
        self.jump_to_page_online_practice() # 跳转到在线练习的第一页
        self.generate_exercise_and_practice() # 生成并显示第一页的题目
        self.difficulty_type=2 # 设置习题卷类型
        self.start_contdown() # 启动倒计时
        self.display_calculations() # 显示计算信息

    def set_page(self):
        '''分页编号'''
        self.page_num = self.expression_quantity // self.LIMIT_NUM  # 整除得到页数
        if self.expression_quantity % self.LIMIT_NUM!= 0:  # 如果有余数，则加一页
            self.page_num += 1
        # 分页处理
        self.pages = [self.rows[i * self.LIMIT_NUM:(i + 1) * self.LIMIT_NUM] for i in range(self.page_num)]
        # 更新页面编号显示
        self.l_page.setText("1")

    def export_exercise(self):
        """导出当前练习的习题到一个JSON文件中。"""
        # 检查是否有可导出的数据
        if not self.current_exercises:
            QMessageBox.warning(self, "警告", "没有可导出的练习数据")
            return  # 如果没有数据，直接返回
        # 显示文件保存对话框
        file_path, _ = QFileDialog.getSaveFileName(self, "保存文件", "", "JSON Files (*.json);;All Files (*)")
        # 检查用户是否选择了文件路径
        if file_path:
            try:
                # 尝试打开文件并写入数据
                with open(file_path, 'w', encoding='utf-8') as f:
                    json.dump(self.current_exercises, f, ensure_ascii=False, indent=4)  # 将数据写入文件
                # 显示成功信息框
                QMessageBox.information(self, "成功", "练习题目已成功导出")
            except Exception as e:
                # 如果发生异常，捕获异常并显示错误信息框
                QMessageBox.critical(self, "错误", f"导出失败: {e}")

    def select_file(self):
        """打开文件对话框，选择文件并加载其中的练习题目。"""
        # 使用QFileDialog显示文件选择对话框
        file_path, _ = QFileDialog.getOpenFileName(self, "选择练习文件", "", "JSON Files (*.json);;All Files (*)")
        # 检查用户是否选择了文件
        if file_path:
            try:
                # 尝试打开并读取文件
                with open(file_path, 'r', encoding='utf-8') as f:
                    imported_exercises = json.load(f)  # 从文件中加载JSON数据
                # 将JSON数据转换为列表，每个元素是一个包含三个子元素的元组
                self.current_exercises = [(item[0], item[1], item[2]) for item in imported_exercises]
                QMessageBox.information(self, "成功", "练习题目已成功导入") # 显示成功信息框
            except Exception as e:
                print(e)    # 如果发生异常，捕获异常并打印错误消息
                QMessageBox.critical(self, "错误", f"导入失败: {e}") # 显示错误信息框

    def start_exercise(self):
        print(self.current_exercises)
        self.rows = [{'calc_id': item[0], 'expression': item[1], 'answer': item[2]} for item in self.current_exercises]
        if len(self.rows) > self.MAX_cals_num:
            # 随机抽取30个元素
            sampled_rows = random.sample(self.rows, self.MAX_cals_num)
            # 将抽取的元素转换成所需的列表格式
            self.rows = [[item['calc_id'], item['expression'], item['answer']] for item in
                         sampled_rows]
            # print(self.rows)
            self.expression_quantity = self.MAX_cals_num
        else:
            # 如果 self.rows 不超过30个元素，则直接转换
            self.rows = [[item['calc_id'], item['expression'], item['answer']] for item in
                         self.rows]
            # print(self.rows)
            self.expression_quantity = len(self.rows)

        print(self.rows)  # 打印转换后的rows以供调试

        self.jump_to_page_online_practice()  # 切换到在线练习页面
        self.generate_exercise_and_practice()  # 根据新的题目集合生成一套新的练习记录
        self.difficulty_type = 2  # 设置难度级别为2（假设是中等难度）
        self.start_contdown()  # 开始倒计时
        self.display_calculations()  # 在界面上显示计算题

    def connect_online_exercise_signals(self):
        # 难度选择按钮，切换相应界面
        self.pb_easy.clicked.connect(self.choose_easy)
        self.pb_medium.clicked.connect(self.choose_medium)
        self.pb_hard.clicked.connect(self.choose_hard)
        # 开始练习按钮，切换到题目界面
        self.pb_previous.clicked.connect(self.switch_pages_pre)
        self.pb_next.clicked.connect(self.switch_pages_next)
        # 点击提交按钮，系统批改题目
        self.pb_submit.clicked.connect(self.submit_exercise)
        # 点击结算，系统显示做题情况统计
        self.pb_settlement.clicked.connect(self.settlement_exercise)
        # 点击下一页，上一页，切换题目
        self.pb_start_0.clicked.connect(self.start_exercise0)
        self.pb_start_1.clicked.connect(self.start_exercise1)

        self.pb_start.clicked.connect(self.start_exercise)
        #错题重练按钮
        self.pushButton.clicked.connect(self.repractice_the_mistakes)
        #导出
        self.pb_export.clicked.connect(self.export_exercise)
        #导入
        self.pb_select_file.clicked.connect(self.select_file)


        # 在算式配置界面，点击返回上一页按钮
        self.pb_back_0.clicked.connect(self.jump_to_page_main)
        self.pb_back_1.clicked.connect(self.jump_to_page_select_difficulty)
        self.pb_back_2.clicked.connect(self.jump_to_page_select_difficulty)
        self.pb_back_3.clicked.connect(self.jump_to_page_select_difficulty)
        self.pb_back_4.clicked.connect(self.jump_to_page_main)
        self.pb_back_5.clicked.connect(self.jump_to_page_main)
        self.pb_back_6.clicked.connect(self.jump_to_page_error_edition_0)
        self.pb_back_7.clicked.connect(self.jump_to_page_main)
        self.pb_back_8.clicked.connect(self.jump_to_page_main)
        self.pb_back_9.clicked.connect(self.jump_to_page_main)
        # 在算式配置界面，点击返回首页按钮
        self.pb_back_home_page_0.clicked.connect(self.jump_to_page_main)
        self.pb_back_home_page_1.clicked.connect(self.jump_to_page_main)
        self.pb_back_home_page_2.clicked.connect(self.jump_to_page_main)
        self.pb_back_home_page_3.clicked.connect(self.jump_to_page_main)
        self.pb_back_home_page_4.clicked.connect(self.jump_to_page_main)
        self.pb_back_home_page_5.clicked.connect(self.jump_to_page_main)
        self.pb_back_home_page_6.clicked.connect(self.jump_to_page_main)
        self.pb_back_home_page_7.clicked.connect(self.jump_to_page_main)
        self.pb_back_home_page_8.clicked.connect(self.jump_to_page_main)
        self.pb_back_home_page_9.clicked.connect(self.jump_to_page_main)

    def generate_calculations0(self):
        """随机获取算式，生成一套习题，由此生成一套练习记录"""
        # difficulty_type=int(difficulty_type)
        # expression_quantity=int(expression_quantity)
        self.limit_time = self.expression_quantity * self.difficulty_type * 20  # 单位 s
        # 算式获取
        try:
            self.rows = self.db.Obtain_the_difficulty_calculations(self.difficulty_type, self.expression_quantity)
        except Exception as e:
            print(f"从数据库获取数据时发生错误: {e}")
            logging.error(f"从数据库获取数据时发生错误: {e}", exc_info=True)
        print(self.rows)
        self.generate_exercise_and_practice()

    def generate_exercise_and_practice(self):
        # 习题生成
        new_exer_id=self.db.add_exercise(self.difficulty_type, 1, self.limit_time, self.expression_quantity)
        print(new_exer_id)
        # new_exer_id = 4
        # 习题与算式匹配
        for row_data in self.rows:
            print(int(row_data[0]))
            self.db.add_matches(new_exer_id,int(row_data[0]))
        # 练习表中增加数据
        # self.new_prac_id = 3
        print(self.user_id)
        print(new_exer_id)
        self.new_prac_id=self.db.add_practice(self.user_id, new_exer_id)
        print(self.new_prac_id)

    def generate_calculations1(self, bracket_quantity):
        """随机获取算式，生成一套习题，由此生成一套练习记录"""
        # difficulty_type=int(difficulty_type)
        # expression_quantity=int(expression_quantity)
        self.limit_time = self.expression_quantity * self.difficulty_type * 20  # 单位 s
        # 算式获取
        # 获取有括号的
        try:
            self.rows = self.db.Obtain_the_difficulty_calculations(4, bracket_quantity)
        except Exception as e:
            print(f"从数据库获取数据时发生错误: {e}")
            logging.error(f"从数据库获取数据时发生错误: {e}", exc_info=True)
        print(self.rows)
        # 获取无括号的

        print(self.expression_quantity)
        print(bracket_quantity)
        non_bracket_quantity = int(self.expression_quantity) - int(bracket_quantity)
        print(non_bracket_quantity)
        try:
            non_bracket_rows = self.db.Obtain_the_difficulty_calculations(3, non_bracket_quantity)
        except Exception as e:
            print(f"从数据库获取数据时发生错误: {e}")
            logging.error(f"从数据库获取数据时发生错误: {e}", exc_info=True)
        print(non_bracket_rows)
        self.rows=self.rows+non_bracket_rows  # 使用 extend 方法添加元素
        list_from_tuple = list(self.rows)
        # 打乱列表的顺序
        random.shuffle(list_from_tuple)
        # 如果需要，可以将列表转换回元组
        self.rows = tuple(list_from_tuple)
        print(self.rows)
        self.generate_exercise_and_practice()

    def draw_charts(self):
        # 从数据库中获取用户的课堂练习结果和日期列表
        results, practice_class_dates_list = self.db.class_practice(self.user_id)
        # 绘制饼图
        # 获取当前日期
        today = datetime.datetime.now().strftime('%Y-%m-%d')
        # 筛选出今日的练习数据
        today_data = [r for r in results if r['class_end_date'] == today]
        # 如果今日有数据，进行以下操作
        if today_data:
            # 从今日数据中获取正确题目数量和总题目数量
            today_right = today_data[0]['class_right_num']
            today_total = today_data[0]['class_total']
            # 设置饼图的标签和大小
            labels = ['正确', '错误']
            sizes = [today_right, today_total - today_right]
            # 创建一个临时的Figure和Axes来绘制饼图
            fig_pie, ax_pie = plt.subplots()
            ax_pie.pie(sizes, labels=labels, autopct='%1.1f%%')
            ax_pie.set_title(f"今日正确率")
            # 保存饼图为图片文件
            pie_image_path = "photo/today_accuracy_pie_chart.png"  # 保存图片的路径
            fig_pie.savefig(pie_image_path)  # 保存饼图为图片文件
            plt.close(fig_pie)  # 关闭临时Figure
            # 使用QPixmap加载并缩放图片，然后在GUI的标签中显示
            pixmap = QPixmap(pie_image_path).scaled(500, 600, Qt.KeepAspectRatio)
            self.label.setPixmap(pixmap)
        # 绘制折线图（近7天正确率）
        recent_dates = []
        recent_percentages = []
        for result in results:
            try:
                date_obj = datetime.datetime.strptime(result['class_end_date'], '%Y-%m-%d')
                if (datetime.datetime.now() - date_obj).days <= 7:
                    right_num = result['class_right_num']
                    total = result['class_total']
                    percentage = right_num / total * 100 if total != 0 else 0
                    recent_dates.append(date_obj.strftime('%m-%d'))
                    recent_percentages.append(percentage)
            except ValueError:
                pass

        if recent_dates and recent_percentages:
            # 创建一个临时的Figure和Axes来保存折线图为图片
            fig_line, ax_line = plt.subplots()
            ax_line.plot(recent_dates, recent_percentages, marker='o')
            ax_line.set_xlabel('日期')
            ax_line.set_ylabel('正确率')
            ax_line.set_title("近7天正确率")
            ax_line.xaxis.set_tick_params(rotation=0)
            ax_line.grid(True)
            line_image_path = "photo/last_7_days_accuracy_line_chart.png"  # 保存图片的路径
            fig_line.savefig(line_image_path)  # 保存折线图为图片文件
            pixmap=QPixmap(line_image_path).scaled(500, 600, Qt.KeepAspectRatio)
            self.label_31.setPixmap(pixmap)
        else:
            print("No data available for the last 7 days.")


if __name__ == "__main__":
    QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
    app = QApplication(sys.argv)
    # 应用样式表
    with open(r'Ui/style.qss', 'r', encoding='utf-8') as f:
        result = f.read()
        app.setStyleSheet(result)
    mainWindow = MainWindow(1)
    mainWindow.show()
    sys.exit(app.exec_())